package com.juyu.miliao.api.service.whitepacket;


import com.alibaba.fastjson.JSONObject;
import com.juyu.miliao.api.constant.NightChatInTheSameCityRedisKey;
import com.juyu.miliao.api.dao.mysql.UserVideoDao;
import com.juyu.miliao.api.dao.redis.usercache.UserCacheVo;
import com.juyu.miliao.api.dao.redis.usercache.UserInfoCache;
import com.juyu.miliao.api.domain.vo.NightChatInTheSameCityVideoCommentVo;
import com.juyu.miliao.api.domain.vo.NightChatInTheSameCityVo;
import com.juyu.miliao.api.util.PageUtil;
import com.juyu.miliao.common.constant.PageConstant;
import com.juyu.miliao.common.domain.BaseQuery;
import com.juyu.miliao.common.domain.PageIndex;
import com.juyu.miliao.common.util.CommonUtil;
import com.juyu.miliao.common.util.PageInfoUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;

import java.time.LocalDateTime;
import java.util.*;

/**
 * 同城夜聊service
 * @author xuanqicheng
 * @create 2019-07-15:12
 */
@Service
public class NightChatInTheSameCityService {

    private static final List<String> userList = new ArrayList<>();
    static {
        userList.add("11141700");
        userList.add("11141800");
        userList.add("11142000");
        userList.add("11142100");
        userList.add("11142200");
        userList.add("11142300");
        userList.add("11142400");
        userList.add("11142600");
        userList.add("11142700");
        userList.add("11142800");
        userList.add("11142900");
        userList.add("11143100");
        userList.add("11143200");
        userList.add("11143700");
        userList.add("11143800");
        userList.add("11144000");
        userList.add("11144500");
        userList.add("11144600");
        userList.add("11144800");
        userList.add("11144900");
        userList.add("11145200");
        userList.add("11145300");
        userList.add("11145400");
        userList.add("11145600");
        userList.add("11145700");
        userList.add("11145800");
        userList.add("11146100");
        userList.add("11146200");
        userList.add("11146300");
        userList.add("11146400");
        userList.add("11146600");
        userList.add("11146800");
        userList.add("11147000");
        userList.add("11147200");
        userList.add("11147400");
        userList.add("11147800");
        userList.add("11147900");
        userList.add("11148000");
        userList.add("11149000");
        userList.add("11149100");
    }

    @Autowired
    private StringRedisTemplate stringRedisTemplate;

    @Autowired
    private UserVideoDao userVideoDao;

    @Autowired
    private UserInfoCache userInfoCache;



    public Object getList(Integer page, Integer pageSize) {

        int startNum = PageUtil.getOffset(page, pageSize);

        int end = startNum+pageSize;

        Set<String> stringSet = stringRedisTemplate.opsForZSet().reverseRange(NightChatInTheSameCityRedisKey
                .NIGHT_CHAT_VIDEO_LIST_KEY, startNum, end);

        List<String> list = new ArrayList<>(stringSet);
        if(list !=null && list.size()>0){
            if(list.size()>0 && list.size()>=pageSize){

                List<NightChatInTheSameCityVo> resultList = new ArrayList<>();

                List<String> newList = list.subList(0, pageSize);

                getObjectToCoverList(resultList, newList);

                return resultList;
            }else if(list.size()>0 && list.size()< pageSize ){

                List<NightChatInTheSameCityVo> resultList = new ArrayList<>();

                List<String> newList = list.subList(0, list.size());

                getObjectToCoverList(resultList, newList);

                int newPageSize = end - newList.size();

                List<NightChatInTheSameCityVo> nightChatVos = getNightChatInTheSameCityRawData(newPageSize,0);
                if(nightChatVos.size()>0){
                    resultList.addAll(nightChatVos);
                }

                return resultList;

            }else {
                List<NightChatInTheSameCityVo> nightChatInTheSameCityVos = getNightChatInTheSameCityRawData(pageSize, startNum);
                return nightChatInTheSameCityVos;
            }
        }else{
            List<NightChatInTheSameCityVo> nightChatInTheSameCityVos = getNightChatInTheSameCityRawData(pageSize, startNum);
            return nightChatInTheSameCityVos;
        }


    }

    /**
     * 将obj对象转换为NightChatInTheSameCityVo
     * @param resultList
     * @param newList
     */
    private void getObjectToCoverList(List<NightChatInTheSameCityVo> resultList, List<String> newList) {
        for (String obj : newList) {

            NightChatInTheSameCityVo chatInTheSameCityVo = JSONObject.parseObject(obj,NightChatInTheSameCityVo.class);

            String loveNumberKey = NightChatInTheSameCityRedisKey.LOVE_NUMBER_BY_VIDEO_KEY+chatInTheSameCityVo.getVideoId();

            long loveNumber = stringRedisTemplate.opsForValue().increment(loveNumberKey,0);

            String commentNumberKey = NightChatInTheSameCityRedisKey.COMMENT_NUMBER_BY_VIDEO_KEY+chatInTheSameCityVo.getVideoId();

            long commentNumber = stringRedisTemplate.opsForValue().increment(commentNumberKey,0);

            UserCacheVo userCacheVo = userInfoCache.getUserCacheInfo(chatInTheSameCityVo.getUserId());
            chatInTheSameCityVo.setNickName(userCacheVo.getNickName())
                    .setAge(userCacheVo.getAge())
                    .setSex(userCacheVo.getSex())
                    .setIcon(userCacheVo.getIcon())
                    .setLove(loveNumber)
                    .setCommentNum(commentNumber);

            resultList.add(chatInTheSameCityVo);

        }

    }

    /**
     * 获取数据库中的原始数据
     * @param pageSize
     * @param startNum
     * @return
     */
    private List<NightChatInTheSameCityVo> getNightChatInTheSameCityRawData(int pageSize, int startNum) {
        Map<String,Object> parameterMap = new HashMap<>(2);
        parameterMap.put("startNum", startNum);
        parameterMap.put("pageSize", pageSize);
        //直接查原始数据
        List<NightChatInTheSameCityVo> nightChatInTheSameCityVos =userVideoDao.selectNightChatList(parameterMap);
        List<NightChatInTheSameCityVo> resultList = null;
        resultList = getRawDataToCoverNightChatInTheSameCityVos(resultList,pageSize, nightChatInTheSameCityVos);

        return resultList;
    }


    public void addInfo(NightChatInTheSameCityVo nightChatInTheSameCityVo) {
        //生成id
        long id = stringRedisTemplate.opsForValue().increment(NightChatInTheSameCityRedisKey
                .NIGHT_CHAT_VIDEO_ID_KEY,1);

        String videoId = NightChatInTheSameCityRedisKey.NEW_DATA_TAG+id;

        nightChatInTheSameCityVo.setVideoId(videoId);

        nightChatInTheSameCityVo.setCreateTime(LocalDateTime.now());

        String conent = JSONObject.toJSONString(nightChatInTheSameCityVo);


        stringRedisTemplate.opsForZSet().add(NightChatInTheSameCityRedisKey.NIGHT_CHAT_VIDEO_LIST_KEY,conent,id);

        /**
         * 根据用户id 缓存数据
         */
        String listByUserKey = NightChatInTheSameCityRedisKey.NIGHT_CHAT_VIDEO_LIST_BY_USER_KEY
                +nightChatInTheSameCityVo.getUserId();

        stringRedisTemplate.opsForZSet().add(listByUserKey,conent,id);

    }


    /**
     * 点赞
     * @param userId
     * @param videoId
     * @return
     */
    public Object clickVideoLove(Long userId, String videoId) {
        JSONObject json = new JSONObject();

        String key = NightChatInTheSameCityRedisKey.LOVE_LOG_BY_USER_KEY+videoId;

        String loveNumberKey = NightChatInTheSameCityRedisKey.LOVE_NUMBER_BY_VIDEO_KEY+videoId;

        boolean bl = stringRedisTemplate.opsForSet().isMember(key,Long.toString(userId));
        //true 此操作为取消点赞
        if(bl){

            stringRedisTemplate.opsForValue().increment(loveNumberKey,-1);
            stringRedisTemplate.opsForSet().remove(key,Long.toString(userId));
            json.put("missage", "remove");
        }else{

            stringRedisTemplate.opsForSet().add(key,Long.toString(userId));

            stringRedisTemplate.opsForValue().increment(loveNumberKey,1);
            json.put("missage", "add");
        }

        return json;
    }

    /**
     * 添加视频评论
     * @param userId
     * @param videoComment
     */
    public void saveVideoComment(Long userId, NightChatInTheSameCityVideoCommentVo videoComment) {

        String content = CommonUtil.null2String(videoComment.getContent());
        videoComment.setContent(content);

        videoComment.setCreateTime(LocalDateTime.now());
        videoComment.setSort(0);
        videoComment.setUserId(userId);

        UserCacheVo userCacheVo = userInfoCache.getUserCacheInfo(userId);

        videoComment.setIcon(userCacheVo.getIcon()).setNickname(userCacheVo.getNickName());

        String idKey = NightChatInTheSameCityRedisKey.NIGHT_CHAT_VIDEO_COMMENT_ID_KEY;

        long id = stringRedisTemplate.opsForValue().increment(idKey,1);

        videoComment.setId(NightChatInTheSameCityRedisKey.VIDEO_COMMENT_NEW_DATA_TAG+id);
        //保存评论信息
        String commontKey = NightChatInTheSameCityRedisKey.NIGHT_CHAT_VIDEO_COMMENT_BY_VIDEO_KEY+videoComment.getVideoId();

        stringRedisTemplate.opsForZSet().add(commontKey,JSONObject.toJSONString(videoComment),id);

        //评论加1
        String commentNumberKey = NightChatInTheSameCityRedisKey.COMMENT_NUMBER_BY_VIDEO_KEY+videoComment.getVideoId();

        stringRedisTemplate.opsForValue().increment(commentNumberKey,1);

    }

    public Object getVideoCommentList(String videoId, BaseQuery baseQuery) {
        Map<String,Object> map = new HashMap<>(2);
        PageInfoUtil.cleanOrder(baseQuery);

        String commontKey = NightChatInTheSameCityRedisKey.NIGHT_CHAT_VIDEO_COMMENT_BY_VIDEO_KEY+videoId;

        List<NightChatInTheSameCityVideoCommentVo> resultList = new ArrayList<>();

        long rows = stringRedisTemplate.opsForZSet().size(commontKey);

        PageIndex pageIndex = PageInfoUtil.getPageIndex(baseQuery.getPageNum(), baseQuery.getPageSize(), rows, false);

        int end = baseQuery.getPageNum()+baseQuery.getPageSize();

        if(pageIndex.getOffset() != PageConstant.OUT_OF_ROWS){

            Set<String> set = stringRedisTemplate.opsForZSet().reverseRange(commontKey, baseQuery.getPageNum(), end);

            List<String> list = new ArrayList<>(set);

            for(String str : list){
                NightChatInTheSameCityVideoCommentVo vo = JSONObject.parseObject(str,NightChatInTheSameCityVideoCommentVo.class);
                resultList.add(vo);
            }
        }

        map.put("rows",rows);

        map.put("comments",resultList);

        return map;
    }

    public Object getListByUserId(long userId, Integer page, Integer pageSize) {
        int startNum = PageUtil.getOffset(page, pageSize);

        int end = startNum+pageSize;

        String videoListByUserKey = NightChatInTheSameCityRedisKey.NIGHT_CHAT_VIDEO_LIST_BY_USER_KEY+userId;

        Set<String> set = stringRedisTemplate.opsForZSet().reverseRange(videoListByUserKey, startNum, end);


        List<String> list = new ArrayList<>(set);

        if(list !=null && list.size()>0){

            if(list.size()>0 && list.size()>=pageSize){

                List<NightChatInTheSameCityVo> resultList = new ArrayList<>();

                List<String> newList = list.subList(0, pageSize);

                getObjectToCoverList(resultList, newList);

                return resultList;
            }else if(list.size()>0 && list.size()< pageSize ){

                List<NightChatInTheSameCityVo> resultList = new ArrayList<>();

                List<String> newList = list.subList(0, list.size());

                getObjectToCoverList(resultList, newList);

                int size = end - newList.size();

                List<NightChatInTheSameCityVo> nightChatVos = getNightChatInTheSameCityByUserIdRawData(userId,size,0);
                if(nightChatVos.size()>0){
                    resultList.addAll(nightChatVos);
                }

                return resultList;

            }else {
                List<NightChatInTheSameCityVo> nightChatInTheSameCityVos = getNightChatInTheSameCityByUserIdRawData(
                        userId,pageSize, startNum);
                return nightChatInTheSameCityVos;
            }
        }else{
            List<NightChatInTheSameCityVo> nightChatInTheSameCityVos = getNightChatInTheSameCityByUserIdRawData(
                    userId,pageSize, startNum);

            return nightChatInTheSameCityVos;
        }
    }

    private List<NightChatInTheSameCityVo> getNightChatInTheSameCityByUserIdRawData(long userId, int pageSize, int startNum) {
        Map<String,Object> parameterMap = new HashMap<>(2);
        parameterMap.put("startNum", startNum);
        parameterMap.put("pageSize", pageSize);
        parameterMap.put("userId",userId);
        //直接查原始数据
        List<NightChatInTheSameCityVo> nightChatInTheSameCityVos =userVideoDao.selectNightChatByUserIdList(parameterMap);
        List<NightChatInTheSameCityVo> resultList = null;
        resultList = getRawDataToCoverNightChatInTheSameCityVos(resultList,pageSize, nightChatInTheSameCityVos);

        return resultList;
    }

    /**
     * 原始数据转换
     * @param pageSize
     * @param nightChatInTheSameCityVos
     * @return
     */
    private List<NightChatInTheSameCityVo> getRawDataToCoverNightChatInTheSameCityVos(
            List<NightChatInTheSameCityVo> resultList,int pageSize, List<NightChatInTheSameCityVo> nightChatInTheSameCityVos) {

        if (nightChatInTheSameCityVos.size() <= pageSize) {
            resultList = nightChatInTheSameCityVos;
        } else {
            resultList = nightChatInTheSameCityVos.subList(0, pageSize);
        }

        for (NightChatInTheSameCityVo obj : resultList) {
            UserCacheVo userCacheVo = userInfoCache.getUserCacheInfo(obj.getUserId());
            obj.setVideoId(NightChatInTheSameCityRedisKey.RAW_DATA_TAG + obj.getVideoId())
                    .setNickName(userCacheVo.getNickName())
                    .setAge(userCacheVo.getAge())
                    .setSex(userCacheVo.getSex())
                    .setIcon(userCacheVo.getIcon());
        }
        return resultList;
    }
}
